﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2010-11-20 13:29:36Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Windows;
using System.Windows.Input;

namespace Outcoder.UI.Xaml.Controls
{
    public class AppBarIconButton : AppBarIconButtonBase
    {
        /* This handler has been promoted to a field because 
         * of an issue with WeakReferences being cleaned up, 
         * and GC.KeepAlive has no effect. */
        readonly EventHandler commandCanExecuteChangedHandler;

        public AppBarIconButton()
        {
            commandCanExecuteChangedHandler = HandleCommandCanExecuteChanged;
			Loaded += HandleLoaded;
			Unloaded += HandleUnloaded;
        }

	    #region Command

        public static readonly DependencyProperty CommandProperty
            = DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(AppBarIconButton),
                new PropertyMetadata(HandleCommandChanged));

        public ICommand Command
        {
            get
            {
                return (ICommand)GetValue(CommandProperty);
            }
            set
            {
                SetValue(CommandProperty, value);
            }
        }

        static void HandleCommandChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            var button = d as AppBarIconButton;
            if (button == null)
            {
                return;
            }

            if (e.OldValue != null)
            {
                ((ICommand)e.OldValue).CanExecuteChanged
                    -= button.commandCanExecuteChangedHandler;
            }

            if (e.NewValue != null)
            {
				var newCommand = (ICommand)e.NewValue;
				newCommand.CanExecuteChanged
					-= button.commandCanExecuteChangedHandler;
				newCommand.CanExecuteChanged
                    += button.commandCanExecuteChangedHandler;
            }

			UpdateEnabledState(button);
        }

        void HandleCommandCanExecuteChanged(object sender, EventArgs e)
        {
            UpdateEnabledState(this);
        }

		static void UpdateEnabledState(AppBarIconButton button)
		{
			ICommand command = button.Command;
			if (command != null)
			{
				button.IsEnabled = command.CanExecute(button.CommandParameter);
			}
		}

        #endregion

        #region CommandParameter

        public static readonly DependencyProperty CommandParameterProperty
            = DependencyProperty.RegisterAttached(
                "CommandParameter",
                typeof(object),
                typeof(AppBarIconButton),
                null);

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        #endregion

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);

            ICommand command = Command;
            if (command != null)
            {
                command.Execute(CommandParameter);
            }
        }

		void HandleLoaded(object sender, RoutedEventArgs e)
		{
			UpdateEnabledState(this);

			var command = Command;
			if (command != null)
			{
				command.CanExecuteChanged -= commandCanExecuteChangedHandler;
				command.CanExecuteChanged += commandCanExecuteChangedHandler;
			}
		}

		void HandleUnloaded(object sender, RoutedEventArgs e)
		{
			var command = Command;
			if (command != null)
			{
				command.CanExecuteChanged -= commandCanExecuteChangedHandler;
			}
		}
    }
}